<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>bmqa_session Component</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javaScript" src="search/search.js"></script>
<link href="bdedox.css" rel="stylesheet" type="text/css"/>
    <style>
      div.hanging {
        padding-left: 0.75in;
        text-indent: -0.50in;
      }
      div.unhanging {
        text-indent:     0in;
      }
      a.glossary {
        font-weight: bold;
        font-style: italic;
      }
    </style>
</head>
<!--
<body onload='searchBox.OnSelectItem(0);'>
-->
<body>

<table border=2 cellspacing=0 cellpadding=0 align=center>
<tr>
 <td valign=top align=center>
 <p align=center><b><i>Quick Links:</i></b></p>
 </td>
 <td valign=top align=center>
 <p align=center>
<a class="qindex" href="group__bmqa.html" target="_blank">bmqa</a> | <a class="qindex" href="group__bmqpi.html" target="_blank">bmqpi</a> | <a class="qindex" href="group__bmqt.html" target="_blank">bmqt</a>
 </td>
 </tr>
 </table>

  </div>
<!-- Generated by Doxygen 1.7.1 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul class="tablist">
      <li><a href="components.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="components.html"><span>Components</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="summary">
<a href="#namespaces">Namespaces</a>  </div>
  <div class="headertitle">
<h1>Component bmqa_session<br/>
<small>
[<a class="el" href="group__bmqa.html">Package bmqa</a>]</small>
</h1>  </div>
</div>
<div class="contents">

<p>Provide access to the BlazingMQ broker.  
<a href="#_details">More...</a></p>
<table class="memberdecls">
<tr><td colspan="2"><h2><a name="namespaces"></a>
Namespaces</h2></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">namespace &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacebmqimp.html">bmqimp</a></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">namespace &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacebmqp.html">bmqp</a></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">namespace &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacebslmt.html">bslmt</a></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">namespace &nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespacebmqa.html">bmqa</a></td></tr>
</table>
<hr/><a name="_details"></a><h2>Detailed Description</h2>
<dl class="user"><dt><b>Outline</b></dt><dd><ul>
<li>
<a href="#1">Purpose</a> </li>
<li>
<a href="#2">Classes</a> </li>
<li>
<a href="#3">Description</a> <ul>
<li>
<a href="#3.1">Disclaimer</a> </li>
<li>
<a href="#3.2">Thread-safety</a> </li>
<li>
<a href="#3.3">Connecting to the Broker</a> </li>
<li>
<a href="#3.4">Connection loss and reconnection</a> <ul>
<li>
<a href="#3.4.1">Example 1</a> </li>
</ul>
</li>
<li>
<a href="#3.5">Processing session events - synchronous mode</a> <ul>
<li>
<a href="#3.5.1">Example 2</a> </li>
</ul>
</li>
<li>
<a href="#3.6">Processing session events - asynchronous mode</a> <ul>
<li>
<a href="#3.6.1">Example 3</a> </li>
</ul>
</li>
<li>
<a href="#3.7">Opening queues</a> <ul>
<li>
<a href="#3.7.1">Example 4</a> </li>
</ul>
</li>
<li>
<a href="#3.8">Closing queues</a> </li>
</ul>
</li>
</ul>
</dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="purpose"></a> <a class="anchor" id="1"></a> </dd></dl>
<dl class="user"><dt><b>Purpose: </b></dt><dd>Provide access to the BlazingMQ broker. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="classes"></a> <a class="anchor" id="2"></a> </dd></dl>
<dl class="user"><dt><b>Classes: </b></dt><dd><table class="doxtable">
<tr>
<td><a class="el" href="classbmqa_1_1SessionEventHandler.html">bmqa::SessionEventHandler</a> </td><td>interface for receiving events asynchronously.  </td></tr>
<tr>
<td><a class="el" href="classbmqa_1_1Session.html">bmqa::Session</a>  </td><td>mechanism for access to the BlazingMQ broker.  </td></tr>
</table>
</dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="description"></a> <a class="anchor" id="3"></a> </dd></dl>
<dl class="user"><dt><b>Description: </b></dt><dd>This component provides a mechanism, <code><a class="el" href="classbmqa_1_1Session.html">bmqa::Session</a></code>, that provides access to a message queue broker and an interface, <code><a class="el" href="classbmqa_1_1SessionEventHandler.html">bmqa::SessionEventHandler</a></code> for asynchronous notification of events. The broker manages named, persistent queues of messages. This broker allows a client to open queues, post messages to them, or retrieve messages from them. All of these operations take place within the context of the session opened by the client application. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Messages received from a broker are communicated to the application by the session associated with that broker in the form of events (see <code>bmqa_event</code>). Events can be of two different types: (1) Messages and message status events (<code><a class="el" href="classbmqa_1_1MessageEvent.html">bmqa::MessageEvent</a></code>), or (2) Session or queue status events (<code><a class="el" href="classbmqa_1_1SessionEvent.html">bmqa::SessionEvent</a></code>). </dd></dl>
<dl class="user"><dt><b></b></dt><dd>A <code>Session</code> can dispatch events to the application in either a synchronous or asynchronous mode. In synchronous mode, the application must call the <code>nextEvent</code> method in order to obtain events from the <code>Session</code>. In asynchronous mode, the application must supply a concrete <code>SessionEventHandler</code> object at construction time. The concrete <code>SessionEventHandler</code> provided by the application must implement the <code>onSessionEvent</code> and <code>onMessageEvent</code> methods, which will be called by the <code>Session</code> every time a session event or a message event is received. Note that by default, a session created in asynchronous mode creates only one internal thread to dispatch events, but a different value for number of threads can be specified in <code><a class="el" href="classbmqt_1_1SessionOptions.html">bmqt::SessionOptions</a></code>. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>A <code>Session</code> is created either in synchronous or in asynchronous mode, and it will remain in that mode until destruction. Allowing a mix between synchronous or asynchronous would make the SDK complicated. The only exceptions are the "start" and "open" operations that must be available in synchronous or asynchronous version for the convenience of the programmer. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>By default a <code>Session</code> connects to the local broker, which in turn may connect to a remote cluster based on configuration. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>After a <code><a class="el" href="classbmqa_1_1Session.html">bmqa::Session</a></code> is started, the application has to open one or several queues in read and/or write mode. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="disclaimer"></a> <a class="anchor" id="description.disclaimer"></a> <a class="anchor" id="3.1"></a> </dd></dl>
<dl class="user"><dt><b>Disclaimer: </b></dt><dd>A <code>Session</code> object is a heavy object representing the negotiated TCP session with the broker, and the entire associated state (opened queues, statistics, ...). Therefore, sessions should be always reused if possible, preferably with only <em>one</em> session per lifetime of a component/library/task. Note that at the time of this writing multiplexing of different logical sessions over the same physical connection is not supported, so in certain circumstances reuse of the same session across the whole of a single application will not be possible. For example, if an application uses two unrelated libraries both of which use BlazingMQ under the hood, they won't be able to share a session as it stands. An example of an extreme inefficiency and an abuse of resources is to create a session ad-hoc every time a message needs to be posted by the same component. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="thread-safety"></a> <a class="anchor" id="description.thread-safety"></a> <a class="anchor" id="3.2"></a> </dd></dl>
<dl class="user"><dt><b>Thread-safety: </b></dt><dd>This session object is <em>thread</em> <em>enabled</em>, meaning that two threads can safely call any methods on the <em>same</em> <em>instance</em> without external synchronization. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="connecting_to_the_broker"></a> <a class="anchor" id="description.connecting_to_the_broker"></a> <a class="anchor" id="3.3"></a> </dd></dl>
<dl class="user"><dt><b>Connecting to the Broker: </b></dt><dd>A <code>Session</code> establishes a communication with a broker service using TCP/IP. Each <code>Session</code> object must be constructed with a <code>bmqa::SessionOptions</code> object, which provides the necessary information to connect to the broker. In particular, the <code>SessionOptions</code> object must specify the IP address and port needed to connect to the broker. The <code>SessionOptions</code> object may also provide extra parameters for tuning the TCP connection behavior (see <code>bmqa_sessionoptions</code> for details). </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Note that in most cases the user does not need to explicitly construct a <code>SessionOptions</code> object: the default constructor for <code>SessionOptions</code> creates an instance that will connect to the broker service on the local machine using the standard port. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Some options can also be provided using environment variables. <ul>
<li>
<b>BMQ_BROKER_URI</b>: Corresponds to <code>SessionOptions::brokerUri</code>. If this environment variable is set, its value will override the one specified in the <code>SessionOptions</code>.  </li>
</ul>
</dd></dl>
<dl class="user"><dt><b></b></dt><dd>A <code>Session</code> object is created in an unconnected state. The <code>start</code> or <code>startAsync</code> method must be called to connect to the broker. Note that <code>start</code> method is blocking, and returns either after connection to broker has been established (success), or after specified timeout (failure). <code>startAsync</code> method, as the name suggests, connects to the broker asynchronously (i.e., it returns immediately), and the result of the operation is notified via <code>bmqt::SessionEventType::CONNECTED</code> session event. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>When the <code>Session</code> is no longer needed, the application should call the <code>stop</code> (blocking) or <code>stopAsync</code> (non-blocking) method to shut down the <code>Session</code> and disconnect from the broker. Note that destroying a Session automatically stops it. The session can be restarted with a call to <code>start</code> or <code>startAsync</code> once it has been fully stopped. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="connection_loss_and_reconnection"></a> <a class="anchor" id="description.connection_loss_and_reconnection"></a> <a class="anchor" id="3.4"></a> </dd></dl>
<dl class="user"><dt><b>Connection loss and reconnection: </b></dt><dd>If the connection between the application and the broker is lost, the <code>Session</code> will automatically try to reconnect periodically. The <code>Session</code> will also notify the application of the event of losing the connection via <code>bmqt::SessionEventType::CONNECTION_LOST</code> session event. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Once the connection has been re-established with the broker (as a result of one of the periodic reconnection attempts), the <code>Session</code> will notify the application via <code>bmqt::SessionEventType::RECONNECTED</code> session event. After the connection re-establishment, the <code>Session</code> will attempt to reopen the queues that were in <code>OPEN</code> state prior to connection loss. The <code>Session</code> will notify the application of the result of reopen operation via <code>bmqt::SessionEventType::QUEUE_REOPEN_RESULT</code> for each queue. Note that a reopen operation on a queue may fail (due to broker issue, machine issue, etc), so the application must keep track on these session events, and stop posting on a queue that failed to reopen. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>After all reopen operations are complete and application has been notified with all <code>bmqt::SessionEventType::QUEUE_REOPEN_RESULT</code> events, the <code>Session</code> delivers a <code>bmqt::SessionEventType::STATE_RESTORED</code> session event to the application. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="example_1"></a> <a class="anchor" id="connection_loss_and_reconnection.example_1"></a> <a class="anchor" id="description.connection_loss_and_reconnection.example_1"></a> <a class="anchor" id="3.4.1"></a> </dd></dl>
<dl class="user"><dt><b>Example 1: </b></dt><dd>The following example illustrates how to create a <code>Session</code> in synchronous mode, start it, and stop it. <div class="fragment"><pre class="fragment">  <span class="keywordtype">void</span> runSession()
  {
      <a class="code" href="classbmqt_1_1SessionOptions.html">bmqt::SessionOptions</a> options;
      options.<a class="code" href="classbmqt_1_1SessionOptions.html#aa46958591fc80e5735f22c70b3ad79c7">setBrokerUri</a>(<span class="stringliteral">&quot;tcp://localhost:30114&quot;</span>);

      <a class="code" href="classbmqa_1_1Session.html">bmqa::Session</a> session(options);
      <span class="keywordtype">int</span> res = session.<a class="code" href="classbmqa_1_1Session.html#a5f8aafcc526a95123bab44f321ee23b6">start</a>();
      <span class="keywordflow">if</span> (0 != res) {
          bsl::cout &lt;&lt; <span class="stringliteral">&quot;Failed to start session (&quot;</span> &lt;&lt; res &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>
                    &lt;&lt; bsl::endl;
          <span class="keywordflow">return</span>;
      }
      bsl::cout &lt;&lt; <span class="stringliteral">&quot;Session started.&quot;</span> &lt;&lt; bsl::endl;

      <span class="comment">// Open queue in READ or WRITE or READ/WRITE mode, and receive or</span>
      <span class="comment">// post messages, etc.</span>
      <span class="comment">// ...</span>

      session.<a class="code" href="classbmqa_1_1Session.html#a8ce13e884cd76e2f60738d8fc0c68722">stop</a>();
  }
</pre></div> This example can be simplified because the constructor for <code>Session</code> uses a default <code>SessionOptions</code> object that will connect to the local broker service. The example may be rewritten as follow: <div class="fragment"><pre class="fragment">  <span class="keywordtype">void</span> runSession()
  {
      <a class="code" href="classbmqa_1_1Session.html">bmqa::Session</a> session;     <span class="comment">// using default &#39;SessionOptions&#39;</span>
      <span class="keywordtype">int</span> res = session.<a class="code" href="classbmqa_1_1Session.html#a5f8aafcc526a95123bab44f321ee23b6">start</a>();
      <span class="keywordflow">if</span> (0 != res) {
          bsl::cout &lt;&lt; <span class="stringliteral">&quot;Failed to start session (&quot;</span> &lt;&lt; res &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>
                    &lt;&lt; bsl::endl;
          <span class="keywordflow">return</span>;
      }
      bsl::cout &lt;&lt; <span class="stringliteral">&quot;Session started.&quot;</span> &lt;&lt; bsl::endl;

      <span class="comment">// Open queue in READ or WRITE or READ/WRITE mode, and receive or</span>
      <span class="comment">// post messages, etc.</span>
      <span class="comment">// ...</span>

      session.<a class="code" href="classbmqa_1_1Session.html#a8ce13e884cd76e2f60738d8fc0c68722">stop</a>();
  }
</pre></div> </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="processing_session_events_-_synchronous_mode"></a> <a class="anchor" id="description.processing_session_events_-_synchronous_mode"></a> <a class="anchor" id="3.5"></a> </dd></dl>
<dl class="user"><dt><b>Processing session events - synchronous mode: </b></dt><dd>If the <code>Session</code> is created in synchronous mode, the application needs to call the <code>nextEvent</code> method on a regular basis in order to receive events. This method takes an optional wait timeout as a parameter, and it will return the next available <code>Event</code> from the session's internal event queue or it will block the calling thread execution until new <code>Event</code> arrives or until the specified timeout expires. It is safe to call the <code>nextEvent</code> method from different threads simultaneously: the <code>Session</code> class provides proper synchronization logic to protect the internal event queue from corruption in this scenario. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="example_2"></a> <a class="anchor" id="processing_session_events_-_synchronous_mode.example_2"></a> <a class="anchor" id="description.processing_session_events_-_synchronous_mode.example_2"></a> <a class="anchor" id="3.5.1"></a> </dd></dl>
<dl class="user"><dt><b>Example 2: </b></dt><dd>The following example demonstrates how to write a function that queries and processes events synchronously. In this example the switch form checks the type of the <code>Event</code> and performs the necessary actions. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>We first define two functions to process <code>SessionEvent</code> and <code>MessageEvent</code>. These functions return <code>true</code> if we should keep processing events and <code>false</code> otherwise (i.e., no more events are expected from the <code>Session</code>). <div class="fragment"><pre class="fragment">  <span class="keywordtype">bool</span> processSessionEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1SessionEvent.html">bmqa::SessionEvent</a>&amp; event)
  {
      <span class="keywordtype">bool</span> result = <span class="keyword">true</span>;
      <span class="keywordflow">switch</span> (event.<a class="code" href="classbmqa_1_1SessionEvent.html#a57c7930a474e344c707b64c0b1cdd075">type</a>()) {

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529a93376e0c6edbbe6ee9354a9677235144" title="Session started.">bmqt::SessionEventType::e_CONNECTED</a>:
          <span class="comment">// The connection to the broker is established (as a result</span>
          <span class="comment">// of a call to the &#39;start&#39; method).</span>
          openQueues();
          startPostingToQueues();
          <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529a45dce28857e18a5788c4fcfa9a74ee64" title="Session terminated.">bmqt::SessionEventType::e_DISCONNECTED</a>:
          <span class="comment">// The connection to the broker is terminated (as a result</span>
          <span class="comment">// of a call to the &#39;stop&#39; method).</span>
          result = <span class="keyword">false</span>;
          <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529aa5b9f03769aef33f9dfe93288e607eaa" title="Lost connection to the broker.">bmqt::SessionEventType::e_CONNECTION_LOST</a>:
          <span class="comment">// The connection to the broker dropped. Stop posting to the queue.</span>
          stopPostingToQueues();
          <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529a3e534d134d4973bdacaba244e6254c95" title="Client&amp;#39;s state has been restored.">bmqt::SessionEventType::e_STATE_RESTORED</a>:
          <span class="comment">// The connection to the broker has been restored (i.e., all queues</span>
          <span class="comment">// have been re-opened. Resume posting to the queue.</span>
          resumePostingToQueues();
          <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529a426065aaa1e1b34894cd0c08c24f84a2" title="The connection to broker timedOut.">bmqt::SessionEventType::e_CONNECTION_TIMEOUT</a>:
          <span class="comment">// The connection to the broker has timed out.</span>
          result = <span class="keyword">false</span>;
          <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529af71bcb215a7a694c998c9bbad13ef273" title="Generic error.">bmqt::SessionEventType::e_ERROR</a>:
          <span class="comment">// Internal error</span>
          bsl::cout &lt;&lt; <span class="stringliteral">&quot;Unexpected session error: &quot;</span>
                    &lt;&lt; <span class="keyword">event</span>.errorDescription() &lt;&lt; bsl::endl;
          <span class="keywordflow">break</span>;

      } <span class="comment">// end switch</span>

      <span class="keywordflow">return</span> result;
  }

  <span class="keywordtype">bool</span> processMessageEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1MessageEvent.html">bmqa::MessageEvent</a>&amp; event)
  {
      <span class="keywordtype">bool</span> result = <span class="keyword">true</span>;
      <span class="keywordflow">switch</span> (event.<a class="code" href="classbmqa_1_1MessageEvent.html#a8a76bb712e1d9c67cfad2b0b0b1462bd">type</a>()) {

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1MessageEventType.html#ab39efa27453f43916b27597953b3f34da57ed70be8dfe25a9bd7b6ec0261ce294">bmqt::MessageEventType::e_PUSH</a>: {
          <span class="comment">// Received a &#39;PUSH&#39; event from the broker.</span>
          <a class="code" href="classbmqa_1_1MessageIterator.html">bmqa::MessageIterator</a> msgIter = <span class="keyword">event</span>.messageIterator();
          <span class="keywordflow">while</span> (msgIter.<a class="code" href="classbmqa_1_1MessageIterator.html#aebcc19c61a0b788c076b1a2ba5cca6bf">nextMessage</a>()) {
              <span class="keyword">const</span> <a class="code" href="classbmqa_1_1Message.html">bmqa::Message</a>&amp; msg = msgIter.<a class="code" href="classbmqa_1_1MessageIterator.html#ac3edf62526982ad45cc7d0bdb1c07478">message</a>();
              <span class="comment">// Process &#39;PUSH&#39; msg here (omitted for brevity)</span>
              <span class="comment">// ...</span>
          }
      } <span class="keywordflow">break</span>;

        <span class="keywordflow">case</span> <a class="code" href="structbmqt_1_1MessageEventType.html#ab39efa27453f43916b27597953b3f34da1628a88261d124fc6df59a8bf2970829">bmqt::MessageEventType::e_ACK</a>: {
          <span class="comment">// Received an &#39;ACK&#39; event from the broker.</span>
          <a class="code" href="classbmqa_1_1MessageIterator.html">bmqa::MessageIterator</a> msgIter = <span class="keyword">event</span>.messageIterator();
          <span class="keywordflow">while</span> (msgIter.<a class="code" href="classbmqa_1_1MessageIterator.html#aebcc19c61a0b788c076b1a2ba5cca6bf">nextMessage</a>()) {
              <span class="keyword">const</span> <a class="code" href="classbmqa_1_1Message.html">bmqa::Message</a>&amp; msg = msgIter.<a class="code" href="classbmqa_1_1MessageIterator.html#ac3edf62526982ad45cc7d0bdb1c07478">message</a>();
              <span class="comment">// Process &#39;ACK&#39; msg here (omitted for brevity)</span>
              <span class="comment">// ...</span>
          }
      } <span class="keywordflow">break</span>;

      } <span class="comment">// end switch</span>

      <span class="keywordflow">return</span> result;
  }
</pre></div> </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Next, we define a function that handles events synchronously using the <code>processSessionEvent</code> and <code>processMessageEvent</code> functions. <div class="fragment"><pre class="fragment">  <span class="keywordtype">void</span> handleEventsSynchronously(<a class="code" href="classbmqa_1_1Session.html">bmqa::Session</a> *startedSession)
  {
      <span class="keywordtype">bool</span> more = <span class="keyword">true</span>;
      <span class="keywordflow">while</span> (more) {
          <a class="code" href="classbmqa_1_1Event.html">bmqa::Event</a> <span class="keyword">event</span> =
                  startedSession-&gt;<a class="code" href="classbmqa_1_1Session.html#a865d173f667d4901324c2ef58e1ec8ba">nextEvent</a>(bsls::TimeInterval(2.0));
          <span class="keywordflow">if</span> (event.isSessionEvent()) {
              more = processSessionEvent(event.sessionEvent());
          }
          <span class="keywordflow">else</span> {
              more = processMessageEvent(event.messageEvent());
          }
      }
  }
</pre></div> </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="processing_session_events_-_asynchronous_mode"></a> <a class="anchor" id="description.processing_session_events_-_asynchronous_mode"></a> <a class="anchor" id="3.6"></a> </dd></dl>
<dl class="user"><dt><b>Processing session events - asynchronous mode: </b></dt><dd>If application wishes to use <code>Session</code> in asynchronous mode, it must pass a managed pointer to an event handler implementing the <code>SessionEventHandler</code>. In this case, when <code>Session</code> is started, a thread pool owned by the <code>Session</code> is also started for processing events asynchronously. The <code>Session</code> will call event handler's <code>onSessionEvent</code> or <code>onMessageEvent</code> method every time a session event or a message event is available. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Note that after the <code>Session</code> is associated with some event handler, this association cannot be changed or canceled. The event handler will be used for processing events until the <code>Session</code> object is destroyed. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="example_3"></a> <a class="anchor" id="processing_session_events_-_asynchronous_mode.example_3"></a> <a class="anchor" id="description.processing_session_events_-_asynchronous_mode.example_3"></a> <a class="anchor" id="3.6.1"></a> </dd></dl>
<dl class="user"><dt><b>Example 3: </b></dt><dd>The following example demonstrates how to implement an event handler and how to make the <code>Session</code> use an instance of this event handler for processing events. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>First, we define a concrete implementation of <code>SessionEventHandler</code>. </dd></dl>
<dl class="user"><dt><b></b></dt><dd><div class="fragment"><pre class="fragment">  <span class="keyword">class </span>MyHandler: <span class="keyword">public</span> bmqa::SessionEventHandler {
  <span class="keyword">public</span>:
      MyHandler() { }
      <span class="keyword">virtual</span> ~MyHandler() { }
      <span class="keyword">virtual</span> <span class="keywordtype">void</span> onSessionEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1SessionEvent.html">bmqa::SessionEvent</a>&amp; event);
      <span class="keyword">virtual</span> <span class="keywordtype">void</span> onMessageEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1MessageEvent.html">bmqa::MessageEvent</a>&amp; event);
  };

  <span class="keywordtype">void</span> MyHandler::onSessionEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1SessionEvent.html">bmqa::SessionEvent</a>&amp; event)
  {
      <span class="comment">// The implementation is similar to our &#39;processSessionEvent&#39; function</span>
      <span class="comment">// defined in the previous example.</span>
      processSessionEvent(event);
  }

  <span class="keywordtype">void</span> MyHandler::onMessageEvent(<span class="keyword">const</span> <a class="code" href="classbmqa_1_1MessageEvent.html">bmqa::MessageEvent</a>&amp; event)
  {
      <span class="comment">// The implementation is similar to our &#39;processMessageEvent&#39; function</span>
      <span class="comment">// defined in the previous example.</span>
      processMessageEvent(event);
  }
</pre></div> Next, we define a function that creates a <code>Session</code> using our implementation of <code>SessionEventHandler</code>. <div class="fragment"><pre class="fragment">  <span class="keywordtype">void</span> runAsyncSession()
  {
      bslma::ManagedPtr&lt;SessionEventHandler&gt; handlerMp(<span class="keyword">new</span> MyHandler());

      <a class="code" href="classbmqa_1_1Session.html">bmqa::Session</a> session(handlerMp);   <span class="comment">// using default &#39;SessionOptions&#39;</span>
      <span class="keywordtype">int</span> res = session.<a class="code" href="classbmqa_1_1Session.html#a5f8aafcc526a95123bab44f321ee23b6">start</a>();
      <span class="keywordflow">if</span> (0 != res) {
          bsl::cout &lt;&lt; <span class="stringliteral">&quot;Failed to start session (&quot;</span> &lt;&lt; res &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>
                    &lt;&lt; bsl::endl;
          <span class="keywordflow">return</span>;
      }

      <span class="comment">// ...</span>

      session.<a class="code" href="classbmqa_1_1Session.html#a8ce13e884cd76e2f60738d8fc0c68722">stop</a>();
  }
</pre></div> </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="opening_queues"></a> <a class="anchor" id="description.opening_queues"></a> <a class="anchor" id="3.7"></a> </dd></dl>
<dl class="user"><dt><b>Opening queues: </b></dt><dd>Once the <code>Session</code> has been created and started, the application can use it to open queues for producing and/or consuming messages. A queue is associated with a domain. Domain metadata must be deployed in the BlazingMQ infrastructure prior to opening queues under that domain, because opening a queue actually loads the metadata deployed for the associated domain. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>The metadata associated with a domain defines various parameters like maximum queue size and capacity, persistent policy, routing policy, etc. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Queue are identified by URIs (Unified Resource Identifiers) that must follow the BlazingMQsyntax, manipulated as <code><a class="el" href="classbmqt_1_1Uri.html">bmqt::Uri</a></code> objects. A queue URI is typically formatted as follows: <div class="fragment"><pre class="fragment">  bmq:<span class="comment">//my.domain/my.queue</span>
</pre></div> Note that domain names are unique in BlazingMQ infrastructure, which makes a fully qualified queue URI unique too. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Queues in BlazingMQ infrastructure are created by applications on demand. Broke creates a queue when it receives an open-queue request from an application for a queue that does not exist currently. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Application can open a queue by calling <code>openQueue</code> or <code>openQueueAsync</code> method on a started session. Application must pass appropriate flags to indicate if it wants to post messages to queue, consume messages from the queue, or both. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Note that <code>openQueue</code> is a blocking method, and returns after specified queue has been successfully opened (success) or after specified timeout has expired (failure). <code>openQueueAsync</code> method, as the name suggests, is non blocking, and the result of the operation is notified via <code>bmqt::SessionEventType::QUEUE_OPEN_RESULT</code> session event. </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="example_4"></a> <a class="anchor" id="opening_queues.example_4"></a> <a class="anchor" id="description.opening_queues.example_4"></a> <a class="anchor" id="3.7.1"></a> </dd></dl>
<dl class="user"><dt><b>Example 4: </b></dt><dd>The following example demonstrates how to open a queue for posting messages. The code first opens the queue with appropriate flags, and then uses <code><a class="el" href="classbmqa_1_1MessageEventBuilder.html">bmqa::MessageEventBuilder</a></code> to build a message event and post to the queue. <div class="fragment"><pre class="fragment">  <span class="comment">// Session creation and startup logic elided for brevity</span>
  <span class="keyword">const</span> <span class="keywordtype">char</span> *queueUri = <span class="stringliteral">&quot;bmq://my.domain/my.queue&quot;</span>;
  <a class="code" href="classbmqa_1_1QueueId.html">bmqa::QueueId</a> myQueueId(1);       <span class="comment">// ID for the queue</span>
  <span class="keywordtype">int</span> rc = session.<a class="code" href="classbmqa_1_1Session.html#a25059f75562d96250889ea230cae2bfd">openQueue</a>(
                      &amp;myQueueId,
                      queueUri,
                      <a class="code" href="structbmqt_1_1QueueFlags.html#a7f1a1e2ba9084565388e19bc1921a4f2a59b29b8ab1dde5e07fd120b88dedc8a0" title="The queue is opened for posting messages.">bmqt::QueueFlags::e_WRITE</a> | <a class="code" href="structbmqt_1_1QueueFlags.html#a7f1a1e2ba9084565388e19bc1921a4f2ac5c22028732543c302b391a6a64b80b2">bmqt::QueueFlags::e_ACK</a>,
                      bsls::TimeInterval(30, 0));

  <span class="keywordflow">if</span> (rc != 0) {
      bsl::cerr &lt;&lt; <span class="stringliteral">&quot;Failed to open queue, rc: &quot;</span>
                &lt;&lt; <a class="code" href="structbmqt_1_1OpenQueueResult.html#ad9ced6521b110ebf4fff8dcac28dad1c" title="GENERIC.">bmqt::OpenQueueResult::Enum</a>(rc)
                &lt;&lt; bsl::endl;
      <span class="keywordflow">return</span>;
  }
</pre></div> Note that apart from <code>WRITE</code> flag, <code>ACK</code> flag has been passed to <code>openQueue</code> method above. This indicates that application is interested in receiving <code>ACK</code> notification for each message it posts to the queue, irrespective of whether or not the message was successfully received by the broker and posted to the queue. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Once the queue has been successfully opened for writing, messages can be posted to the queue for consumption by interested applications. We will use <code><a class="el" href="classbmqa_1_1MessageEventBuilder.html">bmqa::MessageEventBuilder</a></code> to build a message event. <div class="fragment"><pre class="fragment">  <span class="comment">// Create a message event builder</span>
  <a class="code" href="classbmqa_1_1MessageEventBuilder.html">bmqa::MessageEventBuilder</a> builder;
  session.<a class="code" href="classbmqa_1_1Session.html#a898eeb0dd7a3407bb1a2788ae8ecb7ff">loadMessageEventBuilder</a>(&amp;builder);

  <span class="comment">// Create and post a message event containing 1 message</span>
  <a class="code" href="classbmqa_1_1Message.html">bmqa::Message</a>&amp; msg = builder.<a class="code" href="classbmqa_1_1MessageEventBuilder.html#a33d687a643555d8d42ae476c0ad70eaf">startMessage</a>();

  msg.<a class="code" href="classbmqa_1_1Message.html#a13966aa7376c58c8570cf64182ca8f9c">setCorrelationId</a>(myCorrelationId);
  msg.<a class="code" href="classbmqa_1_1Message.html#a979f3d17c493015eb01928c77ec328d4">setDataRef</a>(&amp;myPayload);  <span class="comment">// where &#39;myPayload&#39; is of type &#39;bdlbb::Blob&#39;</span>
  rc = builder.<a class="code" href="classbmqa_1_1MessageEventBuilder.html#a101f3eea6233a4ff2b78b6b8072e3c50">packMessage</a>(myQueueId);
  <span class="keywordflow">if</span> (rc != 0) {
      bsl::cerr &lt;&lt; <span class="stringliteral">&quot;Failed to pack message, rc: &quot;</span>
                &lt;&lt; <a class="code" href="structbmqt_1_1EventBuilderResult.html#a04d8f1ec70faff7c9dce79d82c14844c" title="GENERIC.">bmqt::EventBuilderResult::Enum</a>(rc)
                &lt;&lt; bsl::endl;
      <span class="keywordflow">return</span>;
  }

  <span class="comment">// Post message event</span>
  rc = session.<a class="code" href="classbmqa_1_1Session.html#a6e1d0349415ed25dafc141ad6d68c7e7">post</a>(builder.<a class="code" href="classbmqa_1_1MessageEventBuilder.html#a4998ec39691c9f90d639b554d681a782">messageEvent</a>());
  <span class="keywordflow">if</span> (rc != 0) {
      bsl::cerr &lt;&lt; <span class="stringliteral">&quot;Failed to post message event to the queue, rc: &quot;</span>
                &lt;&lt; <a class="code" href="structbmqt_1_1PostResult.html#a61bdfd3cd65c26eaccf02390c514cd76" title="GENERIC.">bmqt::PostResult::Enum</a>(rc)
                &lt;&lt; bsl::endl;
      <span class="keywordflow">return</span>;
  }

  <span class="comment">// ... post more messages</span>
</pre></div> </dd></dl>
<dl class="user"><dt><b></b></dt><dd></dd></dl>
<dl class="user"><dt><b></b></dt><dd><a class="anchor" id="closing_queues"></a> <a class="anchor" id="description.closing_queues"></a> <a class="anchor" id="3.8"></a> </dd></dl>
<dl class="user"><dt><b>Closing queues: </b></dt><dd>After an application no longer needs to produce or consume messages from a queue, it can be closed by <code>closeQueue</code> or <code>closeQueueAsync</code> method. Note that closing a queue closes an application's "view" on the queue, and may not lead to queue deletion in the broker. A <code>Session</code> does not expose any method to explicitly delete a queue. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>Note that <code>closeQueue</code> is a blocking method and returns after the specified queue has been successfully closed (success) or after specified timeout has expired (failure). <code>closeQueueAsync</code>, as the name suggests, is a non-blocking method, and result of the operation is notified via <code><a class="el" href="structbmqt_1_1SessionEventType.html#aef449af38af76209352bf82f78b92529a4d428f58131e9f81ae4f51e9452eaecd" title="Result of closeQueue operation.">bmqt::SessionEventType::e_QUEUE_CLOSE_RESULT</a></code> session event. </dd></dl>
<dl class="user"><dt><b></b></dt><dd>There are 3 flavors which behave differently with regard to thread blocking and callback execution: | openQueue | openQueueSync | openQueueAsync | configureQueue | configureQueueSync | configureQueueAsync | closeQueue | closeQueueSync | closeQueueAsync | (deprecated Sync) | (Synchronous) | (Asynchronous) -----------|-------------------|----------------------|---------------------- event | unblocks in | unblocks in event | executes callback in handler | internal thread | handler thread (*) | event handler thread | | | nextEvent | unblocks in | unblocks in | executes callback | internal thread | internal thread | in nextEvent thread ----------------------------------------------------------------------------- </dd></dl>
<dl class="user"><dt><b></b></dt><dd>(*) - guarantees unblocking after all previously enqueued events have been emitted to the eventHandler, allowing the user to have proper serialization of events for the given queue (for example no more PUSH messages will be delivered through the eventHandler for the queue after configureQueueSync(maxUnconfirmed = 0) returns). </dd></dl>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Thu Jun 15 2023 11:58:51 by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.1 </small></address>
</body>
</html>
